#ifndef __DETU_MEDIA_VI_PIPE_IMP_H__
#define __DETU_MEDIA_VI_PIPE_IMP_H__

#include "vi_pipe.h"
#include "vi_chn_imp.h"
#include "mutex.h"

#include "hi_common.h"
#include "hi_comm_vi.h"
#include "hi_comm_isp.h"
#include "hi_comm_snap.h"
#include "hi_sns_ctrl.h"

#include <map>
#include <string>
#include <signal.h>

#include <pthread.h>

namespace detu_media
{

class ViMgrImp;

class ViPipeImp: public ViPipe
{

protected:
	ViPipeImp();

	~ViPipeImp();

	friend class ViMgrImp;

public:
	virtual S_Result start(void);

	virtual S_Result stop(void);

	virtual bool isStarted(void);

	virtual S_Result getId(int& id);

	virtual S_Result getChn(const std::string& name, ViChn** ppChn);

	virtual S_Result getExpTime(Uint32_t& expTime);

	virtual S_Result startSnap(const Uint32_t count);

	virtual S_Result stopSnap(void);

	virtual S_Result triggerSnap(void);

	virtual S_Result triggerSnap(const Json::Value& config);

private:

	static void timer_thread(union sigval v);

	static S_Result startIspAdj(void);

	static S_Result stopIspAdj(void);

	static S_Result startIspAdjThread(void);

	static S_Result stopIspAdjThread(void);

	static void* ispAdjThreadFunc(void* param);

	static void* ispThreadFunc(void* param);

	void ispThreadFunc1(void);

	S_Result init(const Json::Value& config);

	S_Result deInit(void);

	bool isInited(void);

	S_Result startIsp(void);

	S_Result stopIsp(void);

	S_Result initChn(const Json::Value& config);

	S_Result deInitChn(void);

	S_Result startChn(void);

	S_Result stopChn(void);

	S_Result initIsp(const Json::Value& config);

	S_Result deInitIsp(void);

	S_Result registerSensorCallback(void);

	S_Result unregisterSensorCallback(void);

	S_Result bindSns(void);

	S_Result unbindSns(void);

	S_Result registerAeLibCallback(void);

	S_Result unregisterAeLibCallback(void);

	S_Result registerAwbLibCallback(void);

	S_Result unregisterAwbLibCallback(void);

	S_Result startIspThread(void);

	S_Result stopIspThread(void);

	S_Result setDCFInfo(void);

private:

	constexpr static const SNAP_NORMAL_ATTR_S defNormalAttr =
	{
		.u32FrameCnt 				= 1,
		.u32RepeatSendTimes 		= 1,
		.bZSL 						= HI_FALSE
	};

	constexpr static const SNAP_PRO_ATTR_S defProAttr =
	{
		.u32FrameCnt 				= 1,
		.u32RepeatSendTimes 		= 1,
		.stProParam 				=
		{
			.enOperationMode 		= OPERATION_MODE_AUTO,
			.stAutoParam 			=
			{
				.au16ProExpStep 	= {256, 256, 256, 256, 256, 256, 256, 256}
			},
			.stManualParam 			=
			{
				.au32ManExpTime 	= {40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000},
				.au32ManSysgain 	= {4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096}
			}
		}
	};

	constexpr static const SNAP_ATTR_S defaultSnapAttr =
	{
#if 1
		.enSnapType 				= SNAP_TYPE_NORMAL,
		.bLoadCCM 					= HI_FALSE,
		{
			.stNormalAttr 			= defNormalAttr
		}
#else
		.enSnapType 				= SNAP_TYPE_PRO,
		.bLoadCCM 					= HI_FALSE,
		{
			.stProAttr 				= defProAttr
		}
#endif
	};

	constexpr static const VI_PIPE_ATTR_S defaultPipeAttr =
	{
		.enPipeBypassMode			= VI_PIPE_BYPASS_NONE,
		.bYuvSkip 					= HI_FALSE,
		.bIspBypass 				= HI_FALSE,
	    .u32MaxW 					= 3968,
	    .u32MaxH 					= 2768,
	    .enPixFmt 					= PIXEL_FORMAT_RGB_BAYER_12BPP,
	    .enCompressMode 			= COMPRESS_MODE_NONE,//COMPRESS_MODE_LINE,
	    .enBitWidth 				= DATA_BITWIDTH_12,
	    .bNrEn 						= HI_TRUE,
	    .stNrAttr 					=
	    {
	        .enPixFmt 				= PIXEL_FORMAT_YVU_SEMIPLANAR_420,
	        .enBitWidth 			= DATA_BITWIDTH_10,
	        .enNrRefSource 			= VI_NR_REF_FROM_RFR,
	        .enCompressMode 		= COMPRESS_MODE_NONE
	    },
	    .bSharpenEn 				= HI_FALSE,
	    .stFrameRate 				=
		{
			.s32SrcFrameRate 		= -1,
			.s32DstFrameRate 		= -1
		},
		.bDiscardProPic 			= HI_FALSE
	};

	constexpr static const ISP_PUB_ATTR_S defaultIspPubAttr =
	{
	    .stWndRect 					=
		{
			.s32X 					= 0,
			.s32Y 					= 0,
			.u32Width 				= 3968,
			.u32Height 				= 2768
		},
	    .stSnsSize 					=
	    {
	    	.u32Width 				= 4056,
			.u32Height 				= 3040
		},
	    .f32FrameRate 				= 25,
	    .enBayer 					= BAYER_RGGB,
	    .enWDRMode 					= WDR_MODE_NONE,
	    .u8SnsMode 					= 0
	};

private:
	static pthread_t fIspAdjThreadId;
	static bool fIsIspAdjStarted;
	static detu_infra::Mutex fStaticMutex;

	typedef std::map<std::string, ViChnImp*> ChnMap;
	ChnMap fChnMap;
	bool fInited;
	int fRef;
	VI_PIPE fPipeId;
	VI_PIPE_ATTR_S fPipeAttr;
	bool fIsSnapPipe;

	HI_S32 fBusId;
	ISP_PUB_ATTR_S fIspPubAttr;
	ISP_SNS_OBJ_S* fIspSnsObj;
	ISP_SNS_TYPE_E fBusType;

	pthread_t fIspThreadId;
	bool fIsIspStarted;

	SNAP_ATTR_S fSnapAttr;

	detu_infra::Mutex fMutex;
};


}

#endif

